<template>
  <div>
    <el-cascader
            v-model="select"
            :options="data"
            :load-data="loadData"
            :disabled="disabled"
            :size="size"
            :placeholder="placeholder"
            :render-format="renderFormat"
            :separator="separator"
            @change="handleChange"
            style="width: 100%"
    />
  </div>
</template>

<script>
import areaData from '@/constants/area';
import util from '../util';
const levelShow = (level, code) => {
    if (level === 2) {
        return Object.keys(areaData['86']).indexOf(code) > -1;
    } else if (level === 3) {
        return true;
    }
};
export default {
    name: 'alCascader',
    props: {
        value: Array,
        level: {
            type: [Number, String],
            default: 3,
            validator: val => {
                return util.checkLevel(parseInt(val));
            }
        },
        dataType: {
            type: String,
            default: 'all',
            validator: val => {
                return util.oneOf(val, util.dataType);
            }
        },
        disabled: {
            type: Boolean,
            default: false
        },
        size: String,
        placeholder: String,
        renderFormat: Function,
        separator: String
    },
    data () {
        return {
            data: [],
            select: [],
            isInit: true,
            oldData: []
        };
    },
    computed: {
        showLevel () {
            return parseInt(this.level);
        }
    },
    methods: {
        init () {
        // code转汉字大对象
            const CodeToText = {};
            // 汉字转code大对象
            const TextToCode = {};
            const provinceObject = areaData['86'];
            const regionData = [];
            for (const prop in provinceObject) {
                regionData.push({
                    value: prop, // 省份code值
                    label: provinceObject[prop] // 省份汉字
                });
                CodeToText[prop] = provinceObject[prop];
                TextToCode[provinceObject[prop]] = {
                    code: prop
                };
                TextToCode[provinceObject[prop]]['全部'] = {
                    code: ''
                };
            }

            // 计算市
            for (let i = 0, len = regionData.length; i < len; i++) {
                const provinceCode = regionData[i].value;
                const provinceText = regionData[i].label;
                const provinceChildren = [];
                for (const prop in areaData[provinceCode]) {
                    provinceChildren.push({
                        value: prop,
                        label: areaData[provinceCode][prop]
                    });
                    CodeToText[prop] = areaData[provinceCode][prop];
                    TextToCode[provinceText][areaData[provinceCode][prop]] = {
                        code: prop
                    };
                    TextToCode[provinceText][areaData[provinceCode][prop]]['全部'] = {
                        code: ''
                    };
                }
                if (provinceChildren.length) {
                    regionData[i].children = provinceChildren;
                }
            }

            if (this.level >= 2) {
                for (let i = 0, len = regionData.length; i < len; i++) {
                    const province = regionData[i].children;
                    const provinceText = regionData[i].label;
                    if (province) {
                        for (let j = 0, len = province.length; j < len; j++) {
                            const cityCode = province[j].value;
                            const cityText = province[j].label;
                            const cityChildren = [];
                            for (const prop in areaData[cityCode]) {
                                cityChildren.push({
                                    value: prop,
                                    label: areaData[cityCode][prop]
                                });
                                CodeToText[prop] = areaData[cityCode][prop];
                                TextToCode[provinceText][cityText][areaData[cityCode][prop]] = {
                                    code: prop
                                };
                            }
                            if (cityChildren.length) {
                                province[j].children = cityChildren;
                            }
                        }
                    }
                }
            }

            this.data = regionData;
        },
        setDefaultValue () {
            if (this.value[0]) {
                let select = [];
                if (isNaN(parseInt(this.value[0]))) {
                    let i = 0;
                    let index = '';
                    while (this.value[i] && i <= this.showLevel) {
                        if (i === 0) {
                            index = util.getIndex(areaData['86'], this.value[0]);
                        } else {
                            index = util.getIndex(areaData[index], this.value[i]);
                        }
                        select.push(index);
                        i++;
                    }
                    this.select = select;
                } else {
                    this.select = this.value;
                }
                let res = this.procesValue(this.select);
                this.oldData = res;
                this.$emit('input', res);
                this.$emit('on-change', res);
            }
        },
        canEmit (res) {
            let ifEmit = false;
            if (this.value && this.value.length !== 0) {
                if (typeof res[0] === 'string') {
                    if (this.value[this.value.length - 1] !== this.oldData[this.oldData.length - 1]) {
                        ifEmit = true;
                    }
                } else {
                    if (this.oldData && this.oldData.length !== 0 && this.value[this.value.length - 1].code !== this.oldData[this.oldData.length - 1].code) {
                        ifEmit = true;
                    }
                }
            } else {
                ifEmit = true;
            }
            return ifEmit;
        },
        handleChange (resArr) {
            let res = this.procesValue(resArr);
            this.oldData = res;
            this.$emit('input', res);
            this.$emit('change', res);
        },
        loadData (item, callback) {
            let childData = [];
            let childs = areaData[item.value];
            for (const c in childs) {
                let childitem = {
                    value: c,
                    label: areaData[item.value][c],
                    children: []
                };
                if (areaData[childitem.value] && levelShow(this.showLevel, item.value)) {
                    childitem.loading = false;
                }
                childData.push(childitem);
                item.children = childData;
            }
            item.loading = false;
            callback();
        },
        procesValue (arr) {
            let i = 0;
            let res = [];
            while (arr[i]) {
                let name = '';
                if (i === 0) {
                    name = areaData['86'][arr[i]];
                } else {
                    name = areaData[arr[i - 1]][arr[i]];
                }
                let item;
                if (this.dataType === 'all') {
                    item = {
                        code: arr[i],
                        name: name
                    };
                } else if (this.dataType === 'name') {
                    item = name;
                } else {
                    item = arr[i];
                }
                res.push(item);
                i++;
            }
            return res;
        }
    },
    mounted () {
        this.init();
        if (this.canEmit(this.value)) {
            this.setDefaultValue();
        }
    },
    watch: {
        value (val) {
            if (this.canEmit(this.value)) {
                this.setDefaultValue();
            }
        }
    }
};
</script>
